home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 3.iso / dist / fw_qt3.idb / usr / freeware / Qt / tutorial / t13 / cannon.cpp.z / cannon.cpp
Encoding:
C/C++ Source or Header  |  2002-04-08  |  4.7 KB  |  232 lines

  1. /****************************************************************
  2. **
  3. ** Implementation CannonField class, Qt tutorial 13
  4. **
  5. ****************************************************************/
  6.  
  7. #include "cannon.h"
  8. #include <qtimer.h>
  9. #include <qpainter.h>
  10. #include <qpixmap.h>
  11. #include <qdatetime.h>
  12.  
  13. #include <math.h>
  14. #include <stdlib.h>
  15.  
  16.  
  17. CannonField::CannonField( QWidget *parent, const char *name )
  18.         : QWidget( parent, name )
  19. {
  20.     ang = 45;
  21.     f = 0;
  22.     timerCount = 0;
  23.     autoShootTimer = new QTimer( this, "movement handler" );
  24.     connect( autoShootTimer, SIGNAL(timeout()),
  25.          this, SLOT(moveShot()) );
  26.     shoot_ang = 0;
  27.     shoot_f = 0;
  28.     target = QPoint( 0, 0 );
  29.     gameEnded = FALSE;
  30.     setPalette( QPalette( QColor( 250, 250, 200) ) );
  31.     newTarget();
  32. }
  33.  
  34.  
  35. void CannonField::setAngle( int degrees )
  36. {
  37.     if ( degrees < 5 )
  38.     degrees = 5;
  39.     if ( degrees > 70 )
  40.     degrees = 70;
  41.     if ( ang == degrees )
  42.     return;
  43.     ang = degrees;
  44.     repaint( cannonRect(), FALSE );
  45.     emit angleChanged( ang );
  46. }
  47.  
  48.  
  49. void CannonField::setForce( int newton )
  50. {
  51.     if ( newton < 0 )
  52.     newton = 0;
  53.     if ( f == newton )
  54.     return;
  55.     f = newton;
  56.     emit forceChanged( f );
  57. }
  58.  
  59.  
  60. void CannonField::shoot()
  61. {
  62.     if ( isShooting() )
  63.     return;
  64.     timerCount = 0;
  65.     shoot_ang = ang;
  66.     shoot_f = f;
  67.     autoShootTimer->start( 50 );
  68.     emit canShoot( FALSE );
  69. }
  70.  
  71.  
  72. void  CannonField::newTarget()
  73. {
  74.     static bool first_time = TRUE;
  75.     if ( first_time ) {
  76.     first_time = FALSE;
  77.     QTime midnight( 0, 0, 0 );
  78.     srand( midnight.secsTo(QTime::currentTime()) );
  79.     }
  80.     QRegion r( targetRect() );
  81.     target = QPoint( 200 + rand() % 190,
  82.              10  + rand() % 255 );
  83.     repaint( r.unite( targetRect() ) );
  84. }
  85.  
  86. void CannonField::setGameOver()
  87. {
  88.     if ( gameEnded )
  89.     return;
  90.     if ( isShooting() )
  91.     autoShootTimer->stop();
  92.     gameEnded = TRUE;
  93.     repaint();
  94. }
  95.  
  96. void CannonField::restartGame()
  97. {
  98.     if ( isShooting() )
  99.     autoShootTimer->stop();
  100.     gameEnded = FALSE;
  101.     repaint();
  102.     emit canShoot( TRUE );
  103. }
  104.  
  105. void CannonField::moveShot()
  106. {
  107.     QRegion r( shotRect() );
  108.     timerCount++;
  109.  
  110.     QRect shotR = shotRect();
  111.  
  112.     if ( shotR.intersects( targetRect() ) ) {
  113.     autoShootTimer->stop();
  114.     emit hit();
  115.     emit canShoot( TRUE );
  116.     } else if ( shotR.x() > width() || shotR.y() > height() ) {
  117.     autoShootTimer->stop();
  118.     emit missed();
  119.     emit canShoot( TRUE );
  120.     } else {
  121.     r = r.unite( QRegion( shotR ) );
  122.     }
  123.  
  124.     repaint( r );
  125. }
  126.  
  127.  
  128. void CannonField::paintEvent( QPaintEvent *e )
  129. {
  130.     QRect updateR = e->rect();
  131.     QPainter p( this );
  132.  
  133.     if ( gameEnded ) {
  134.     p.setPen( black );
  135.     p.setFont( QFont( "Courier", 48, QFont::Bold ) );
  136.     p.drawText( rect(), AlignCenter, "Game Over" );
  137.     }
  138.     if ( updateR.intersects( cannonRect() ) )
  139.     paintCannon( &p );
  140.     if ( isShooting() && updateR.intersects( shotRect() ) )
  141.     paintShot( &p );
  142.     if ( !gameEnded && updateR.intersects( targetRect() ) )
  143.     paintTarget( &p );
  144. }
  145.  
  146.  
  147. void CannonField::paintShot( QPainter *p )
  148. {
  149.     p->setBrush( black );
  150.     p->setPen( NoPen );
  151.     p->drawRect( shotRect() );
  152. }
  153.  
  154.  
  155. void CannonField::paintTarget( QPainter *p )
  156. {
  157.     p->setBrush( red );
  158.     p->setPen( black );
  159.     p->drawRect( targetRect() );
  160. }
  161.  
  162.  
  163. const QRect barrelRect(33, -4, 15, 8);
  164.  
  165. void CannonField::paintCannon( QPainter *p )
  166. {
  167.     QRect cr = cannonRect();
  168.     QPixmap pix( cr.size() );
  169.     pix.fill( this, cr.topLeft() );
  170.  
  171.     QPainter tmp( &pix );
  172.     tmp.setBrush( blue );
  173.     tmp.setPen( NoPen );
  174.  
  175.     tmp.translate( 0, pix.height() - 1 );
  176.     tmp.drawPie( QRect( -35,-35, 70, 70 ), 0, 90*16 );
  177.     tmp.rotate( -ang );
  178.     tmp.drawRect( barrelRect );
  179.     tmp.end();
  180.  
  181.     p->drawPixmap( cr.topLeft(), pix );
  182. }
  183.  
  184.  
  185. QRect CannonField::cannonRect() const
  186. {
  187.     QRect r( 0, 0, 50, 50 );
  188.     r.moveBottomLeft( rect().bottomLeft() );
  189.     return r;
  190. }
  191.  
  192.  
  193. QRect CannonField::shotRect() const
  194. {
  195.     const double gravity = 4;
  196.  
  197.     double time      = timerCount / 4.0;
  198.     double velocity  = shoot_f;
  199.     double radians   = shoot_ang*3.14159265/180;
  200.  
  201.     double velx      = velocity*cos( radians );
  202.     double vely      = velocity*sin( radians );
  203.     double x0        = ( barrelRect.right()  + 5 )*cos(radians);
  204.     double y0        = ( barrelRect.right()  + 5 )*sin(radians);
  205.     double x         = x0 + velx*time;
  206.     double y         = y0 + vely*time - 0.5*gravity*time*time;
  207.  
  208.     QRect r = QRect( 0, 0, 6, 6 );
  209.     r.moveCenter( QPoint( qRound(x), height() - 1 - qRound(y) ) );
  210.     return r;
  211. }
  212.  
  213.  
  214. QRect CannonField::targetRect() const
  215. {
  216.     QRect r( 0, 0, 20, 10 );
  217.     r.moveCenter( QPoint(target.x(),height() - 1 - target.y()) );
  218.     return r;
  219. }
  220.  
  221.  
  222. bool CannonField::isShooting() const
  223. {
  224.     return autoShootTimer->isActive();
  225. }
  226.  
  227.  
  228. QSizePolicy CannonField::sizePolicy() const
  229. {
  230.     return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
  231. }
  232.